package oas.db.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import oas.db.LeaveTypeRepository;
import oas.db.UserLeaveRepository;
import oas.db.UserRepository;
import oas.domain.Leave;
import oas.domain.LeaveType;
import oas.domain.User;
import oas.web.PaginationSupport;

/**
 * 用户申请请假DAO
 *
 * @author Dzq
 * @version v1.2.0
 */

@Repository
public class JdbcUserLeaveRepository implements UserLeaveRepository {

    private JdbcTemplate jdbc;

    /**
     * 注入jdbcTemplate
     *
     * @param jdbc
     */
    @Autowired
    public JdbcUserLeaveRepository(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    @Autowired
    private LeaveTypeRepository leaveTypeRepository;

    @Autowired
    private UserRepository userRepository;

    private class LeaveRowMapper implements RowMapper<Leave> {

        @Override
        public Leave mapRow(ResultSet rs, int rowNum) throws SQLException {
            Long id = rs.getLong("applicantId");
            Long handlerId = rs.getLong("handlerId");
            User applicant = userRepository.findById(id.intValue());
            User handler = userRepository.findById(handlerId.intValue());
            Date handleTime = rs.getTimestamp("handleTime");
            Long leaveTypeId = rs.getLong("leaveTypeId");
            LeaveType leaveType = leaveTypeRepository.findById(leaveTypeId);
            return new Leave(rs.getLong("id"), applicant, rs.getTimestamp("applyTime"), handler, handleTime, rs.getString("status"), leaveType);
        }

    }

    /**
     * 添加一个请假记录，用于员工申请请假
     *
     * @param leave
     * @return
     */
    @Override
    public Leave save(Leave leave) {
        jdbc.update(INSERT_LEAVE_TO_AUDIT, leave.getApplicant().getId(), leave.getApplyDate(), leave.getStatus(), leave.getType().getId());
        return leave;
    }

    /**
     * 查找指定页面大小下某一页的数据
     *
     * @param pageNo
     * @param pageSize
     * @param user
     * @return
     */
    @Override
    public PaginationSupport<Leave> findPage(int pageNo, int pageSize, User user) {
        int totalCount = (int) count(user);
        int startIndex = PaginationSupport.convertFromPageToStartIndex(pageNo, pageSize);
        if (totalCount < 1) {
            return new PaginationSupport<Leave>(new ArrayList<Leave>(), 0);
        }

        List<Leave> items = jdbc.query(SELECT_LEAVE_PAGE, new LeaveRowMapper(), user.getId(), pageSize, startIndex);
        PaginationSupport<Leave> ps = new PaginationSupport<Leave>(items, totalCount, pageSize, startIndex);
        return ps;
    }

    /**
     * 个人请假记录的总数
     *
     * @param user
     * @return 个人请假记录总数
     */
    @Override
    public long count(User user) {
        return jdbc.queryForLong("select count(id) from `leave` where applicantId = ?", user.getId());
    }

    /**
     * 根据id查找请假记录
     *
     * @param id
     * @return 请假记录
     */
    @Override
    public Leave findById(Long id) {
        try {
            return jdbc.queryForObject(SELECT_LEAVE_BY_ID, new LeaveRowMapper(), id);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }


    private static final String INSERT_LEAVE_TO_AUDIT = "insert into `leave` (applicantId,applyTime,status,leaveTypeId) values(?,?,?,?)";
    private static final String SELECT_LEAVE_PAGE = "select id, applicantId, applyTime, handlerId, handleTime, status, leaveTypeId "
            + "from `leave` where applicantId = ? " + "order by id limit ? offset ?";
    private static final String SELECT_LEAVE_BY_ID = "select id, applicantId, applyTime, handlerId, handleTime,status, leaveTypeId "
            + "from `leave` where id = ?";

}
